using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Deepcode.Flux.Core.Data;

namespace Deepcode.Flux.Core.Systems.Workflow.Bases
{
	/// <summary>
	/// Manager class workflow tasks
	/// </summary>
	public class Tasks : BaseManager
	{
		#region Constructors
		public Tasks() : base() { }
		public Tasks(SqlConnection CurrentConnection) : base(CurrentConnection) { }
		public Tasks(SqlConnection CurrentConnection, SqlTransaction CurrentTransaction) : base(CurrentConnection, CurrentTransaction) { }
		#endregion
		#region Data Retrieval
		/// <summary>
		/// Gets a task by it's ID
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public Task GetTasksByID( int ID )
		{
			DataTable result = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFTasksGetByID");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ID));
			da.Fill(result);
			ReleaseConnection();

			if (result == null) return null;
			if (result.Rows.Count < 1) return null;

			return new Task(result.Rows[0]);
		}
		/// <summary>
		/// Gets all non system tasks for a particular handler code and data ID
		/// </summary>
		/// <param name="HandlerCodeID"></param>
		/// <param name="DataID"></param>
		/// <returns></returns>
		public Task [] GetNonSystemTasksFor( string HandlerCodeID, int DataID )
		{
			DataTable results = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFTasksGetNonSystemTasksFor");
			da.SelectCommand.Parameters.Add( SQLUtility.ParameterIn("@HandlerCodeID", SqlDbType.NVarChar, 50, HandlerCodeID));
			da.SelectCommand.Parameters.Add( SQLUtility.ParameterIn("@DataID", SqlDbType.Int, 4, DataID));
			da.Fill( results );
			ReleaseConnection();

			List<Task> list = new List<Task>();
			foreach( DataRow r in results.Rows )
				list.Add( new Task( r ));

			return list.ToArray();
		}
		/// <summary>
		/// Gets any system tasks on the system that have expired
		/// </summary>
		/// <returns></returns>
		public Task [] GetSystemTasksExpired()
		{
			DataTable results = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFTasksGetSystemTasksExpired");
			da.Fill( results );
			ReleaseConnection();

			List<Task> list = new List<Task>();
			foreach( DataRow r in results.Rows )
				list.Add( new Task( r ));

			return list.ToArray();
		}
		/// <summary>
		/// Get any tasks for a specific operator or list of groups
		/// </summary>
		/// <param name="OperatorID"></param>
		/// <param name="CSVGroupListIDs"></param>
		/// <returns></returns>
		public Task [] GetOperatorTasks( int OperatorID, string CSVGroupListIDs )
		{
			DataTable results = new DataTable();

			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFTasksGetOperatorTasks");
			da.SelectCommand.Parameters.Add( SQLUtility.ParameterIn("@OperatorID", SqlDbType.Int, 4, OperatorID));
			da.SelectCommand.Parameters.Add( SQLUtility.ParameterIn("@GroupList", SqlDbType.NVarChar, 500, CSVGroupListIDs));
			da.Fill( results );
			ReleaseConnection();

			List<Task> list = new List<Task>();
			foreach (DataRow r in results.Rows)
			{
				Task newtask = new Task(r);
				bool exists = false;
				
				foreach (Task t in list)
				{
					if (t.FK_TaskingID == newtask.FK_TaskingID &&
						t.FK_DataID == newtask.FK_DataID)
					{
						exists = true;
						break;
					}
				}
				if( ! exists )
					list.Add(new Task(r));
			}

			return list.ToArray();
		}		
		#endregion
		#region Utility methods
		/// <summary>
		/// Determines if any tasks are running for the definition ID specified
		/// </summary>
		/// <param name="DefinitionID"></param>
		/// <returns></returns>
		public bool TasksExistForDefinition( int DefinitionID )
		{
			DataTable results = new DataTable();
			
			EstablishConnection();
			SqlDataAdapter da = this.CreateDataAdapter("coreWFTasksExistForDefinitionID");
			da.SelectCommand.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, DefinitionID));
			da.Fill(results);
			ReleaseConnection();

			if( results == null ) return false;
			if( results.Rows.Count < 1 ) return false;

			int TaskCount = SQLUtility.DBNull( results.Rows[0]["TaskCount"], 0);
			if( TaskCount > 0 ) return true;
			return false;
		}
		#endregion
		#region Save Records
		/// <summary>
		/// Saves the specified task to the database
		/// </summary>
		/// <param name="def"></param>
		/// <returns></returns>
		public int Save(Task t)
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksSave");
			SqlParameter result = SQLUtility.ParameterInOut("@id", SqlDbType.Int, 4, t.PK_ID);
			cmd.Parameters.Add(result);

			cmd.Parameters.Add( SQLUtility.ParameterIn("@HandlerCodeID", SqlDbType.NVarChar, 50, t.HandlerCodeID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_DefinitionID", SqlDbType.Int, 4, t.FK_DefinitionID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_ProcessID", SqlDbType.Int, 4, t.FK_ProcessID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_TaskingID", SqlDbType.Int, 4, t.FK_TaskingID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_ForOperatorID", SqlDbType.Int, 4, t.FK_ForOperatorID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_ForOperatorGroupID", SqlDbType.Int, 4, t.FK_ForOperatorGroupID) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@ForSystem", SqlDbType.Bit, 1, t.ForSystem) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@ForSystemExecDT", SqlDbType.DateTime, 8, t.ForSystemExecDT) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@StartDT", SqlDbType.DateTime, 8, t.StartDT) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@DueDT", SqlDbType.DateTime, 8, t.DueDT) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@TaskCaption", SqlDbType.NVarChar, 500, t.TaskCaption) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@DataItemText", SqlDbType.NVarChar, 1000, t.DataItemText) );
			cmd.Parameters.Add( SQLUtility.ParameterIn("@FK_DataID", SqlDbType.Int, 4, t.FK_DataID) );

			cmd.ExecuteNonQuery();
			ReleaseConnection();

			if( t.PK_ID == -1 )
				t.PK_ID = (int) result.Value;

			return t.PK_ID;
		}
		#endregion
		#region Record Deletions
		/// <summary>
		/// Delete a single task by it's ID
		/// </summary>
		/// <param name="ID"></param>
		/// <returns></returns>
		public bool DeleteByID( int ID )
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksDeleteByID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();

			return true;
		}
		/// <summary>
		/// Delete all tasks against a specific tasking
		/// </summary>
		/// <param name="TaskingID"></param>
		/// <returns></returns>
		public bool DeleteByTaskingID( int TaskingID )
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksDeleteByTskingID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, TaskingID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();

			return true;
		}
		/// <summary>
		/// Delete all tasks against a specific process
		/// </summary>
		/// <param name="ProcessID"></param>
		/// <returns></returns>
		public bool DeleteByProcessID( int ProcessID )
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksDeleteByProcessID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, ProcessID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();

			return true;
		}
		/// <summary>
		/// Delete all tasks for a specific workflow definition
		/// </summary>
		/// <param name="DefinitionID"></param>
		/// <returns></returns>
		public bool DeleteByDefinitionID( int DefinitionID )
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksDeleteByDefinitionID");
			cmd.Parameters.Add(SQLUtility.ParameterIn("@id", SqlDbType.Int, 4, DefinitionID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();

			return true;
		}
		/// <summary>
		/// Delete all tasks for a specific handler type and data record ID
		/// </summary>
		/// <param name="HandlerCodeID"></param>
		/// <param name="DataID"></param>
		/// <returns></returns>
		public bool DeleteByHandlerAndDataID( string HandlerCodeID, int DataID )
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksDeleteByHandlerAndDataID");
			cmd.Parameters.Add( SQLUtility.ParameterIn("@HandlerCodeID", SqlDbType.NVarChar, 50, HandlerCodeID));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@DataID", SqlDbType.Int, 4, DataID ));
			cmd.ExecuteNonQuery();
			ReleaseConnection();
			return true;
		}
		/// <summary>
		/// Delete all tasks against a particular tasking and particular record ID
		/// </summary>
		/// <param name="TaskingID"></param>
		/// <param name="DataID"></param>
		/// <returns></returns>
		public bool DeleteByTaskingAndDataID( int TaskingID, int DataID )
		{
			EstablishConnection();
			SqlCommand cmd = this.CreateSqlCommand("coreWFTasksDeleteByTaskingAndDataID");
			cmd.Parameters.Add( SQLUtility.ParameterIn("@TaskingID", SqlDbType.Int, 4, TaskingID));
			cmd.Parameters.Add( SQLUtility.ParameterIn("@DataID", SqlDbType.Int, 4, DataID));
			cmd.ExecuteNonQuery();
			ReleaseConnection();

			return true;
		}
		#endregion
	}
}
